#pragma once
#ifndef VECTOR4_H_
#define VECTOR4_H_

#include <math.h>

namespace EPOC
{
	class Vector4
	{
	public:
		Vector4() : m_fX(0.0f), m_fY(0.0f), m_fZ(0.0f), m_fW(0.0f){};
		Vector4(float fX, float fY, float fZ) : m_fX(fX), m_fY(fY), m_fZ(fZ), m_fW(0.0f){};

		virtual float Length()				{ return sqrtf( ( m_fX * m_fX ) + ( m_fY * m_fY ) + ( m_fZ * m_fZ ) + ( m_fW * m_fW )); }
		virtual float LengthSq()			{ return ( m_fX * m_fX ) + ( m_fY * m_fY ) + ( m_fZ * m_fZ ) + ( m_fW * m_fW ); }
		virtual void Normalize()			{ float fLength = Length(); m_fX /= fLength; m_fY /= fLength; m_fZ /= fLength; m_fW /= fLength;}
		virtual Vector4 NormalizeCopy()		{ Vector4 vNormalized; float fLength = Length(); vNormalized.m_fX = m_fX / fLength; vNormalized.m_fY = m_fY / fLength; vNormalized.m_fZ = m_fZ / fLength; vNormalized.m_fW = m_fW / fLength;return vNormalized; }

		virtual float DotProduct(Vector4 *pVector)	{ return m_fX * pVector->m_fX + m_fY * pVector->m_fY + m_fZ * pVector->m_fZ + m_fW * pVector->m_fW; }
		//virtual Vector4 Perpendicular()				{ Vector4 vPerpendicular; vPerpendicular.m_fX = -m_fY; vPerpendicular.m_fY = m_fX; return vPerpendicular; }
		
		const Vector4 Vector4::operator+(const Vector4 &other) const 
		{
			Vector4 result = *this;  

			result.m_fX += other.m_fX;
			result.m_fY += other.m_fY;
			result.m_fZ += other.m_fZ;
			result.m_fW += other.m_fW;
		
			return result;            
		}

		const Vector4 Vector4::operator-(const Vector4 &other) const 
		{
			Vector4 result = *this;  
			
			result.m_fX -= other.m_fX;
			result.m_fY -= other.m_fY;
			result.m_fZ -= other.m_fZ;
			result.m_fW -= other.m_fW;
		
		
			return result;           
		}

		const Vector4 Vector4::operator*(const float &other) const 
		{
			Vector4 result = *this; 
			result.m_fX *= other;
			result.m_fY *= other;
			result.m_fZ *= other;
			result.m_fW *= other;
		
			return result;           
		}

		const Vector4 Vector4::operator/(const float &other) const 
		{
			Vector4 result = *this; 
			result.m_fX /= other;
			result.m_fY /= other;
			result.m_fZ /= other;
			result.m_fW /= other;
		
			return result;           
		}

		Vector4& Vector4::operator+=(const Vector4& right)
		{
			*this = *this + right;
			return *this;
		}

		Vector4& Vector4::operator-=(const Vector4& right)
		{
			*this = *this - right;
			return *this;
		}

		Vector4& Vector4::operator*=(const float& right)
		{
			*this = *this * right;
			return *this;
		}

		Vector4& Vector4::operator/=(const float& right)
		{
			*this = *this / right;
			return *this;
		}

		bool Vector4::operator==(const Vector4 &other) const 
		{
			return (this->m_fX == other.m_fX && this->m_fY == other.m_fY && this->m_fZ == other.m_fZ && this->m_fW == other.m_fW);
		}

		bool Vector4::operator!=(const Vector4 &other) const 
		{
			return !(*this == other);
		}

	public:
		float m_fX;
		float m_fY;
		float m_fZ;
		float m_fW;
	
	}; // class Vector4
}; // namespace EPOC

#endif